﻿using System.Collections.Generic;
using System.Linq;

#if !NETFX_CORE && !UNIVERSAL
using System.Windows;
using System.Windows.Controls;
#else
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
#endif

namespace Prometheus.Binding.Core
{
    /// <summary>
    /// Form can host prometheus bindings.
    /// </summary>
    public class proFormBase : ContentControl
    {
#pragma warning disable 1591
        public proFormBase()
#pragma warning restore 1591
        {
            Unloaded += OnUnloaded;
        }

        private void OnUnloaded(object sender, RoutedEventArgs routedEventArgs)
        {
        }

        internal void KillAllBindings()
        {
            var toDelete =
                proBindingBase.BoundControls.Where(b => b.Key.ProFormBase == this).ToArray();

            foreach (var pair in toDelete)
            {
                proBindingBase.BoundControls.Remove(pair.Key);
            }
        }

        #region Utility

        /// <summary>
        /// Get all bindings on this form
        /// </summary>
        public IEnumerable<proBindingBase> GetjBindingByParentIsThis()
        {
            return proBindingBase.BoundControls
                .Where(bc => bc.Key.ProFormBase == this /*&& string.IsNullOrEmpty(bc.Key.BindingGroup)*/)
                .Select(bc => bc.Key)
                .ToArray();//todo: надо подумать в виде чего это вообще возвращать
        }

        /// <summary>
        /// Get bindings of provided group on this form
        /// </summary>
        public IEnumerable<proBindingBase> GetjBindingByParentIsThisAndBindingGroup(string bindingGroupName)
        {
            return
                proBindingBase.BoundControls.Where(
                    bc => bc.Key.ProFormBase == this && bc.Key.BindingGroup == bindingGroupName).Select(bc => bc.Key).ToArray();
        }

        #endregion

        #region Binding setting

        /// <summary>
        /// Binds the control property to any path from datacontext
        /// </summary>
        internal static void SetproBinding(FrameworkElement element, proBindingBase bindingBase)
        {
            bindingBase.Follow(element);
        }

        /// <summary>
        /// Returns first binding of provided control
        /// </summary>
        internal static proBindingBase GetproBinding(FrameworkElement element)
        {
            return proBindingBase.BoundControls.FirstOrDefault(b => b.Value == element).Key;
        }

        #endregion

        /// <summary>
        /// Updates target on all bindings on this form
        /// </summary>
        public void UpdateTarget()
        {
            foreach (proBindingBase element in GetjBindingByParentIsThis())
            {
                element.UpdateTarget();
            }
        }

        /// <summary>
        /// Updates target on bindings in provided group on this form
        /// </summary>
        /// <param name="bindingGroupName">Name of the group of bindings</param>
        public void UpdateTarget(string bindingGroupName)
        {
            foreach (var element in GetjBindingByParentIsThisAndBindingGroup(bindingGroupName))
            {
                element.UpdateTarget();
            }
        }

        /// <summary>
        /// Returns set of bindings which belongs to provided control
        /// </summary>
        public static proBindingBase[] GetBindingsByElement(UIElement element)
        {
            return proBindingBase.BoundControls.Where(bc=>bc.Value==element).Select(bc=>bc.Key).ToArray();
        }
    }
}